#include "async_fsync.h"

#include <algorithm>
#include <cstdlib>
#include <memory>
#include <mutex>
#include <unistd.h>
#include <syslog.h>
#include <errno.h>
#include <pthread.h>

namespace Base {
namespace SystemLog {

AsyncFsync& AsyncFsync::GetInstance() {
    static std::unique_ptr<AsyncFsync> instance;
    static std::once_flag flag;
    static std::atomic<bool> destroyed{false};
    
    // 如果已经被销毁，就不要再创建或访问
    if (destroyed.load()) {
        // 创建一个临时的 dummy 实例来避免崩溃
        static AsyncFsync dummy(true);
        return dummy;
    }
    
    std::call_once(flag, []() {
        instance.reset(new AsyncFsync());
        // 注册atexit处理器来标记销毁状态
        std::atexit([]() {
            destroyed.store(true);
        });
    });
    
    // 确保实例存在
    if (!instance) {
        static AsyncFsync dummy(true);
        return dummy;
    }
    
    return *instance;
}

AsyncFsync::AsyncFsync() : running_(true), syncInterval_(10000) {
    worker_ = std::thread([this] { WorkerThread(); });
    
    // 设置线程名称
    auto handle = worker_.native_handle();
    pthread_setname_np(handle, "async_fsync");
}

AsyncFsync::AsyncFsync(bool isDummy) : running_(false), syncInterval_(10000) {
    // dummy 实例不启动工作线程
    (void)isDummy;
}

AsyncFsync::~AsyncFsync() {
    // 提前设置停止标志
    running_.store(false);
    cond_.notify_one();
    if (worker_.joinable()) {
        worker_.join();
    }
    // 清理状态
    fds_.clear();
    immediateSyncFds_.clear();
}

void AsyncFsync::AddFile(int fd) {
    if (fd < 0) return;
    
    std::lock_guard<std::mutex> lock(mutex_);
    fds_.insert(fd);
    cond_.notify_one();
}

void AsyncFsync::RemoveFile(int fd) {
    // 检查运行状态，如果已经停止则直接返回
    if (!running_.load()) {
        return;
    }
    
    std::lock_guard<std::mutex> lock(mutex_);
    fds_.erase(fd);
    immediateSyncFds_.erase(fd);
}

void AsyncFsync::RequestImmediateSync(int fd) {
    if (fd < 0) return;
    
    std::lock_guard<std::mutex> lock(mutex_);
    if (fds_.find(fd) != fds_.end()) {
        immediateSyncFds_.insert(fd);
        immediateSync_.store(true);
        cond_.notify_one();
    }
}

void AsyncFsync::RequestImmediateSyncAll() {
    std::lock_guard<std::mutex> lock(mutex_);
    immediateSyncFds_ = fds_;  // 复制所有文件描述符
    immediateSync_.store(true);
    cond_.notify_one();
}

void AsyncFsync::SetSyncInterval(uint32_t intervalMs) {
    syncInterval_ = std::chrono::milliseconds(intervalMs);
}

void AsyncFsync::RequestStop() {
    running_.store(false);
    cond_.notify_one();
    if (worker_.joinable()) {
        worker_.join();
    }
}

void AsyncFsync::Restart() {
    // 确保先停止
    RequestStop();
    
    // 清理状态
    {
        std::lock_guard<std::mutex> lock(mutex_);
        fds_.clear();
        immediateSyncFds_.clear();
        immediateSync_.store(false);
    }
    
    // 重新启动
    running_.store(true);
    worker_ = std::thread([this] { WorkerThread(); });
    
    // 设置线程名称
    auto handle = worker_.native_handle();
    pthread_setname_np(handle, "async_fsync");
}

size_t AsyncFsync::GetFileCount() const {
    std::lock_guard<std::mutex> lock(mutex_);
    return fds_.size();
}

void AsyncFsync::WorkerThread() {
    while (running_.load()) {
        std::vector<int> localFds;
        std::vector<int> immediateFds;
        
        {
            std::unique_lock<std::mutex> lock(mutex_);
            
            // 等待条件：停止信号、有立即同步请求或超时
            cond_.wait_for(lock, syncInterval_, [this] { 
                return !running_ || immediateSync_.load() || !fds_.empty(); 
            });
            
            if (!running_) break;
            
            // 处理立即同步请求
            if (immediateSync_.load()) {
                immediateFds.assign(immediateSyncFds_.begin(), immediateSyncFds_.end());
                immediateSyncFds_.clear();
                immediateSync_.store(false);
            }
            
            // 定期同步所有文件
            localFds.assign(fds_.begin(), fds_.end());
        }
        
        // 先处理立即同步的文件
        if (!immediateFds.empty()) {
            SyncFiles(immediateFds);
        }
        
        // 然后处理定期同步
        if (!localFds.empty()) {
            SyncFiles(localFds);
        }
    }
    
    // 最后同步所有文件
    std::lock_guard<std::mutex> lock(mutex_);
    if (!fds_.empty()) {
        std::vector<int> finalFds(fds_.begin(), fds_.end());
        SyncFiles(finalFds);
    }
}

void AsyncFsync::SyncFiles(const std::vector<int>& fds) {
    for (int fd : fds) {
        if (fd >= 0) {
            int result = fsync(fd);
            if (result != 0) {
                syslog(LOG_WARNING, "AsyncFsync: fsync failed for fd %d, errno: %d", fd, errno);
            }
        }
    }
}
} // namespace SystemLog
} // namespace Base
